#ifndef __studies_architecture_processing__access_controller__h__
#define __studies_architecture_processing__access_controller__h__



/** @file */


/** @todo */

// ==> C++ Headers
#include <string>

// ==> 3rds Headers

// ==> Our Headers
#include <studies.architecture.returns/codes.h>
#include <studies.architecture.bussiness/login.h>
#include <studies.architecture.bussiness/password.h>



// ==> Namespaces
using namespace std;

// ==> Macro Constants

// ==> Macro Commands


/** ==> namespace of the organization */
namespace studies {
    /** ==> namespace for the project */
    namespace architecture {
        /** ==> displaying, interacting, transmitting, message, processing,
            object, storing */  
        namespace processing {

            // ==> Typedefs 

            // ==> Pre-Declarations

            // ==> Attributes 

            // ==> Functions

            // ==> Classes

            /** 
                @nosubgrouping 
            */
            template <typename t_supplier>
            class access_controller {

                // ==> access_controller - Friends

                /** Class allowed to access private members of @p access_controller, in
                    order to perform tests */
                friend class access_controller_tester;

            public:

                // ==> access_controller - Public Internal Types

                /** */
                typedef t_supplier supplier;

                /** */
                typedef typename supplier::login_storage login_storage;
                

                // ==> access_controller - Public Constructors

                /** Destructor */
                ~access_controller( ) {}
                

                // ==> access_controller - Public Accessors

                // ==> access_controller - Public Helpers

                // ==> access_controller - Public Processors

                /** */
                returns::codes is_access_valid(const std::string & p_login,
                                               const std::string & p_pwd) {
                    try {
                        bussiness::login l_login(p_login);
                        bussiness::password l_pwd(p_pwd);

                        bussiness::password l_pwd_aux;
                        
                        if (!m_login_storage.select(l_login, l_pwd_aux)) {
                            return returns::codes::LOGIN_INEXISTENT;
                        }
                        
                        if (l_pwd != l_pwd_aux) {
                            return returns::codes::PWD_DOES_NOT_MATCH;
                        }
                    } catch (returns::codes & l_code) {
                        return l_code;
                    }
                    
                    return returns::codes::OK;
                }
                

                // ==> access_controller - Public Operators

                // ==> access_controller - Public Attributes

            private:

                // ==> access_controller - Private Internal Types

                // ==> access_controller - Private Constructors

                // ==> access_controller - Private Accessors

                // ==> access_controller - Private Helpers

                // ==> access_controller - Private Processors

                // ==> access_controller - Private Operators

                // ==> access_controller - Private Attributes

                /** */
                login_storage m_login_storage;
                
            };
        }
    }
}
// =============================================================================
// I M P L E M E N T A T I O N
// =============================================================================

using namespace studies::architecture::processing;


#endif
